/**
 * 1.需要光学头API指令(0.5d)
 * 2.需要脚本配置模块(0.5d)
 * 3.需要重写自动化的工具依赖(1d)
 * 4.迁移自动化脚本(1d)
 * 5.测试(0.5d)
 * 6.配置方面(0.5d)
 */
type CommandParam = {
    name: string;
    bit_length: number;
    type: 'uint' | 'int';
    default: string | number;
    enum?: Record<string, string>;
    min?: number;
    max?: number;
};

type CommandConfig = {
    label: string;
    params: CommandParam[];
};

class OpticalCommand {
    private fHead: string;
    private sourceAddr: string;
    private fTail: string;
    private excludedParams: Set<string>;
    
    constructor(
        config: { 
            fHead?: string, 
            sourceAddr?: string, 
            fTail?: string,
            excludeParams?: string[]
        } = {}
    ) {
        this.fHead = config.fHead || 'EB90';
        this.sourceAddr = config.sourceAddr || '22';
        this.fTail = config.fTail || '09D7';
        this.excludedParams = new Set(config.excludeParams || [
            '帧头', '源地址', '数据长度', '目的地址', 
            '指令码', '校验和', '帧尾'
        ]);
    }

    // 核心处理方法
    private commandHandler(params: Record<string, any>, commandConfig: CommandConfig): Uint8Array {
        let hexStr = '';
        const argLengths: number[] = [];
        
        // 处理每个参数
        for (const paramConfig of commandConfig.params) {
            if (this.excludedParams.has(paramConfig.name)) continue;
            
            const value = params[paramConfig.name] ?? paramConfig.default;
            const bits = paramConfig.bit_length;
            argLengths.push(bits);

            // 处理枚举值转换
            if (paramConfig.enum) {
                const enumKey = Object.entries(paramConfig.enum).find(
                    ([, desc]) => desc === value)?.[0];
                if (enumKey) {
                    hexStr += this.processValue(enumKey, bits);
                    continue;
                }
            }

            hexStr += this.processValue(value, bits);
        }

        // 构建完整帧
        const dataHex = this.buildFrame(commandConfig, hexStr);
        return this.hexToBytes(dataHex);
    }

    private processValue(value: string | number, bits: number): string {
        let numValue: number;
        
        if (typeof value === 'string') {
            if (value.startsWith('0x')) {
                return value.slice(2).padStart(bits / 4, '0');
            }
            numValue = parseInt(value, 10);
        } else {
            numValue = value;
        }

        // 处理负数补码
        if (numValue < 0) {
            const maxVal = Math.pow(2, bits);
            numValue = maxVal + numValue;
        }

        return numValue.toString(16)
            .padStart(bits / 4, '0')
            .toUpperCase();
    }

    private buildFrame(config: CommandConfig, dataHex: string): string {
        // 获取固定参数
        const fixedParams = config.params.reduce((acc, param) => {
            if (!this.excludedParams.has(param.name)) return acc;
            acc[param.name] = param.default;
            return acc;
        }, {} as Record<string, any>);

        // 计算数据长度（单位：字节）
        const dataLength = (dataHex.length / 2).toString(16)
            .padStart(2, '0').toUpperCase();

        // 构造基础帧
        let frame = [
            this.fHead,
            this.sourceAddr,
            fixedParams['目的地址'],
            dataLength,
            fixedParams['指令码'],
            dataHex
        ].join('');

        // 计算校验和
        const bytes = this.hexToBytes(frame);
        const checksum = bytes.reduce((sum, byte) => sum + byte, 0) % 256;
        frame += checksum.toString(16).padStart(2, '0').toUpperCase();
        
        return frame + this.fTail;
    }

    private hexToBytes(hex: string): Uint8Array {
        const bytes = new Uint8Array(hex.length / 2);
        for (let i = 0; i < hex.length; i += 2) {
            bytes[i/2] = parseInt(hex.substr(i, 2), 16);
        }
        return bytes;
    }

    // 动态生成指令方法
    static createCommandMethods(configs: CommandConfig[]): Record<string, (params?: any) => { send: () => void, cmdBytes: Uint8Array }> {
        const methods: Record<string, any> = {};
        
        for (const config of configs) {
            const methodName = config.label.replace(/[()/]/g, '').replace(/\s+/g, '_');
            
            methods[methodName] = function(this: OpticalCommand, params: any = {}) {
                // 合并默认参数
                const mergedParams = config.params.reduce((acc, param) => {
                    if (param.name in params) {
                        acc[param.name] = params[param.name];
                    } else {
                        acc[param.name] = param.default;
                    }
                    return acc;
                }, {} as Record<string, any>);

                // 生成指令字节
                const cmdBytes = this.commandHandler(mergedParams, config);
                
                return {
                    cmdBytes,
                    send: () => {
                        // 实际发送逻辑需要根据通信方式实现
                        console.log('Sending:', cmdBytes);
                    }
                };
            }
        }
        
        return methods;
    }
}

// 使用示例
const commandConfigs: CommandConfig[] = [/* 你的JSON配置 */];

class OpticalHead extends OpticalCommand {
    constructor(config?: any) {
        super(config);
        
        // 动态添加指令方法
        const methods = OpticalCommand.createCommandMethods(commandConfigs);
        Object.assign(OpticalHead.prototype, methods);
    }

    // 可以添加其他通用方法
    getTelemetry(timeout: number = 2000): Promise<any> {
        return Promise.resolve(/* ... */);
    }
}

// 使用示例
const optical = new OpticalHead();
let s = optical["FSM控制_调试"]({
    设置位置X: 100,
    设置位置Y: -200,
    设置方式: '位置闭环'
}).send();
console.log(s)